home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / qbarcv.arc / QBARCV.ASM next >
Assembly Source File  |  1987-01-01  |  18KB  |  917 lines

  1.     page    74,132
  2.     title    ARCV - Verbose ARC directory listing
  3.  
  4. ;    Special version of ARCV to be called by QB program
  5. ; usage:
  6. ;
  7. ;    CALL ARCV ( "filename[.ARC]", RETCD%)
  8. ;
  9. ; notes:
  10. ;    Change 9/14/86 to dis-allow wildcards
  11. ;    Change 1/1/87 to recognize squash format
  12.  
  13. print    macro    name            ; display a field
  14.     mov    dx,offset name
  15.     call    prints
  16.     endm
  17.  
  18. printl    macro    text            ; display a literal
  19.     local    txt,nxt
  20.     mov    dx,offset txt
  21.     call    prints
  22.     jmp    nxt
  23. txt    db    cr,lf,text
  24.     db    stopper
  25. nxt    equ    $
  26.     endm
  27.  
  28.  
  29. header    struc                ; archive header
  30. mbrcode db    0            ;  compression code
  31. mbrname db    13 dup (0)        ;  file name
  32. mbrsize dw    0,0            ;  file size in archive
  33. mbrdate dw    0            ;  creation date
  34. mbrtime dw    0            ;  creation time
  35. mbrcrc    dw    0            ;  cyclic redunancy check
  36. mbrlen    dw    0,0            ;  true file size, bytes
  37. header    ends
  38.  
  39.  
  40. cseg    segment public para 'CODE'
  41.     assume    cs:cseg,ds:cseg,es:cseg
  42.  
  43.     public    arcv
  44. arcv    proc    far
  45.     push    bp            ; save BASIC reg
  46.     mov    bp,sp            ; get parameter list pointer
  47.     mov    cs:stkptr,sp        ; save stack ptr
  48.     mov    cs:saveds,ds        ; save QB seg reg
  49.     mov    cs:savees,es        ; save QB seg reg
  50.     mov    cs:errlvl,0        ; init return code
  51.     jmp    start            ; do our thing
  52.  
  53. ;    return with error
  54.  
  55. error:    mov    ax,cs            ; insure seg regs
  56.     mov    ds,ax            ;  for proper exit
  57.     mov    es,ax
  58.     mov    sp,cs:stkptr
  59.     mov    errlvl,1        ; set bad return code
  60.     jmp    arcv2a            ; produce totals anyway
  61.  
  62. ;    set DOS error level and exit
  63.  
  64. exit:    mov    sp,cs:stkptr        ; restore entry stack value
  65.  
  66.     mov    bx,word ptr cs:outhdl    ; close listing file
  67.     or    bx,bx            ; if it was opened
  68.     jz    exiting
  69.     mov    ah,3eh
  70.     int    21h
  71. exiting:
  72.     push    ds            ; restore QB dta
  73.     mov    dx,word ptr cs:savedta[2]
  74.     mov    ds,word ptr cs:savedta
  75.     mov    ah,1ah
  76.     int    21h
  77.     pop    ds
  78.  
  79.     mov    ds,word ptr cs:saveds    ; recover QB seg regs
  80.     mov    es,word ptr cs:savees
  81.     mov    al,cs:errlvl        ; get return code
  82.     cbw
  83.     mov    bp,sp            ; parm ptr from entry
  84.     mov    di,word ptr 6[bp]    ; ptr to retcd variable
  85.     stosw
  86.     pop    bp
  87.     ret    4            ; clear parms from stack
  88.  
  89.     subttl    '--- constants, equates and work areas'
  90.     page
  91.  
  92. cr    equ    13
  93. lf    equ    10
  94. bel    equ    7
  95. tab    equ    9
  96.  
  97. stopper equ    0        ; end of display line indicator
  98. arcmark equ    26        ; special archive marker
  99. arcver    equ    9        ; highest compression code used
  100.  
  101. stkptr    dw    0        ; stack pointer upon entry
  102. errlvl    db    0        ; dos error level returned
  103. flags    db    0        ; find-first return code
  104.  
  105. archdl    dw    0        ; file handle
  106.  
  107. arctitl db    cr,lf,'Archive:  '
  108. arcname db    76 dup (stopper)
  109.  
  110. fileptr dw    0        ; ptr to filename part of arcname
  111. savedta dw    0,0        ; addr of QB dta
  112. dta    db    48 dup (0)    ; data transfer area
  113.  
  114. saveds    dw    0        ; QB seg reg
  115. savees    dw    0        ; QB seg reg
  116. outhdl    dw    1        ; handle for output listing
  117. temp    db    'temparc.dir',0 ; and temporary file name
  118.  
  119.     subttl    '--- i/o control variables'
  120.     page
  121.  
  122. inbufsz equ    512        ; size of input buffer
  123. inadr    dw    offset inbuf    ; offset to input buffer
  124. inptr    dw    offset inbuf    ; offset to current byte
  125. insize    dw    inbufsz     ; size of input buffer
  126. inlen    dw    0        ; bytes left in buffer
  127. incurh    dw    0        ; current file offset
  128. incurl    dw    0        ;  low word
  129.  
  130. usage    db    cr,lf
  131.     db    'ARCV 1.15d - Verbose ARC directory display - V.Buerg'
  132.     db    cr,lf,lf,'  Usage:  arcv [d:][\path\]filespec[.ARC]'
  133.     db    cr,lf,stopper
  134.  
  135. ;    display lines for verbose
  136.  
  137. vhdr    db    cr,lf
  138.     db    cr,lf,'Name          Length    Stowage    SF   Size now  Date       Time    CRC '
  139.     db    cr,lf,'============  ========  ========  ====  ========  =========  ======  ===='
  140.     db    stopper
  141.  
  142. vline    db    cr,lf
  143. vname    db    14 dup (' ')
  144. vlength db    '       0  '    ; length in archive
  145. vstyle    db    '          '    ; compression method
  146. vfactor db    ' xx%  '        ; compression factor
  147. vsize    db    10 dup (' ')    ; actual file bytes
  148. vdate    db    'dd '           ; creation date
  149.  vmonth db    'mmm '
  150.  vyear    db    'yy  '
  151.  vtime    db    'hh:mm   '      ; creation time
  152.  vcrc    db    'xxxx'          ; crc in hex
  153.     db    stopper
  154.  
  155. hundred dw    100        ; for computing percentages
  156. totsf    dw    0,0        ; average stowage factor
  157. totlen    dw    0,0        ; total of file lengths
  158. totsize dw    0,0        ; total of file sizes
  159. totmbrs dw    0        ; total number of files
  160.  
  161. ;    final totals line
  162.  
  163. vthdr    db    cr,lf,'*total    '
  164.  vtmbrs db    '    '
  165.  vtlen    db    8 dup (' '),'  '
  166.     db    10 dup (' ')
  167.  vtsf    db    '   %  '
  168.  vtsize db    8 dup (' ')
  169.     db    cr,lf        ; for tom
  170.     db    stopper
  171.  sign    db    ' '
  172.  
  173. styles    db    '  ----- '      ; 1 = old, no compression
  174.     db    '  ----- '      ; 2 = new, no compression
  175.     db    ' Packed '      ; 3 = dle for repeat chars
  176.     db    'Squeezed'      ; 4 = huffman encoding
  177.     db    'crunched'      ; 5 = lz, no dle
  178.     db    'crunched'      ; 6 = lz with dle
  179.     db    'Crunched'      ; 7 = lz with readjust
  180.     db    'Crunched'      ; 8 = lz with readjust and dle
  181.     db    'Squashed'      ; 9 = 13-bit lz with no dle
  182.  
  183. months    db    'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec '
  184.  
  185.     subttl    '--- mainline processing'
  186.     page
  187. ;
  188. ;    determine if command line or menu driven mode
  189.  
  190. start:
  191.     push    ds
  192.     mov    ax,cs            ; set local seg regs
  193.     mov    ds,ax
  194.     mov    es,ax
  195.     mov    word ptr inlen,ax    ; initialize file variables
  196.     mov    word ptr incurh,ax
  197.     mov    word ptr incurl,ax
  198.     mov    dx,offset temp        ; open temporary file for output
  199.     mov    cx,0
  200.     mov    ah,3ch
  201.     int    21h
  202.     mov    outhdl,ax
  203.     pop    ds
  204.     jnc    parm0
  205.     mov    cs:errlvl,1        ; return error code
  206.     jmp    exit
  207.  
  208. parm0:    mov    si,word ptr 8[bp]    ; ptr to parameter vector
  209.     lodsw                ; get string length
  210.     mov    cx,ax
  211.     mov    si,word ptr [si]    ; get string offset
  212.     or    cx,cx            ; any operand?
  213.     jnz    parm1
  214.     print    usage
  215.     jmp    exit
  216.  
  217. ;    copy firt command line operand
  218.  
  219. parm1:; inc    si            ; point to operand
  220. parm2:    lodsb                ; strip leading blanks
  221.     cmp    al,' '
  222.     loope    parm2
  223.     mov    di,offset arcname
  224.     stosb
  225. parm3:    lodsb                ; copy filename
  226.     cmp    al,cr            ; end of name?
  227.     je    parm4
  228.     cmp    al,' '                  ; don't know why this is here
  229.     je    parm4
  230.     stosb
  231.     loop    parm3
  232.  
  233. ;    find filename part
  234.  
  235. parm4:
  236.     mov    ax,cs            ; need local seg regs
  237.     mov    ds,ax
  238.     mov    es,ax
  239.  
  240.     mov    si,offset arcname+75    ; end of filename stuff
  241.     std
  242.     mov    cl,76            ; search for last path
  243. parm5:
  244.     lodsb
  245.     cmp    al,'/'                  ; funny path delimiter?
  246.     je    parm6
  247.     cmp    al,'\'                  ; normal path delimiter?
  248.     je    parm6
  249.     cmp    al,':'                  ; bumped into drive?
  250.     je    parm6
  251.     loop    parm5
  252.     dec    si
  253. parm6:
  254.     cld
  255.     add    si,2            ; point to where filename goes
  256.     mov    fileptr,si        ; and save for later
  257.  
  258. ;    add default ARC extension if necessary
  259.  
  260.     mov    si,fileptr        ; start of filespec
  261.     mov    cx,13
  262. parm10:
  263.     lodsb
  264.     cmp    al,0            ; end of name?
  265.     je    parm11
  266.     cmp    al,'.'                  ; got extension?
  267.     je    parm12
  268.     loop    parm10
  269. parm11:
  270.     mov    di,si            ; ptr to end of name
  271.     dec    di
  272.     mov    ax,'A.'                 ; default extension
  273.     stosw
  274.     mov    ax,'CR'
  275.     stosw
  276.     mov    ax,0FF00h        ; append stoppers
  277.     stosw
  278. parm12:
  279.  
  280. ;    find first matching file
  281.  
  282. getfirst:
  283.     push    es
  284.     mov    ah,2fh            ; get current dta ptr
  285.     int    21h            ; returned in es:bx
  286.     mov    word ptr savedta,es
  287.     mov    word ptr savedta[2],bx
  288.     pop    es
  289.  
  290.     mov    dx,offset dta        ; set local dta for murkers
  291.     mov    ah,1ah
  292.     int    21h
  293.  
  294. ;    mov    dx,offset arcname    ; find first matching file
  295. ;    sub    cx,cx            ; normal attribute
  296. ;    mov    ah,4eh
  297. ;    int    21h
  298. ;    mov    flags,al        ; indicate find-first status
  299. ;    or    ax,ax            ; any return code?
  300. ;    jz    parm7
  301.     jmp    not_found        ; in case of DPATH utility
  302. nofiles:
  303. ;    printl    'No file(s) found'
  304. ;    mov    errlvl,2
  305. ;    jmp    error
  306.  
  307. getnext:
  308. ;    mov    ah,4fh            ; get next file name
  309. ;    int    21h
  310. ;    jc    alldone
  311. ;    or    ax,ax
  312. ;    jz    parm7
  313. alldone:
  314.     jmp    exit
  315.  
  316. ;    set up next matching file name
  317.  
  318. parm7:
  319.     mov    si,offset dta+30    ; point to filename found
  320.     mov    di,fileptr        ; and overlay old name
  321.     mov    cx,13
  322.     rep    movsb
  323.  
  324. ;    re-initialize
  325.  
  326. not_found:
  327.     sub    ax,ax            ; reset totals counters
  328.     mov    totmbrs,ax
  329.     mov    totsize,ax
  330.     mov    totsize+2,ax
  331.     mov    totlen,ax
  332.     mov    totlen+2,ax
  333.     mov    totsf,ax
  334.     mov    inlen,ax
  335.     mov    incurl,ax
  336.     mov    incurh,ax
  337.     mov    dx,offset inbuf
  338.     mov    inptr,dx
  339.  
  340.     call    openarc         ; see if archive exists
  341.     jnc    arcv1
  342.     jmp    exit
  343.  
  344.     page
  345. ;
  346. ;    process next archive header entry
  347.  
  348. arcv1:    print    arctitl
  349.     print    vhdr
  350.  
  351. arcvnext:
  352.     call    gethdr            ; load next header
  353.     jnc    arcv2
  354.     jmp    exit            ; all done
  355.  
  356. arcv2:    cmp    archdr.mbrcode,0    ; archive eof?
  357.     je    arcv2a
  358.     jmp    arcvgo
  359.  
  360. arcv2a:
  361.     mov    ax,totmbrs        ; total files
  362.     or    ax,ax            ; are there any?
  363.     jnz    format_totals
  364.     jmp    skip_totals
  365.  
  366. format_totals:
  367.     sub    dx,dx
  368.     mov    si,offset vtmbrs-4
  369.     call    format
  370.  
  371.     mov    dx,totlen+2        ; total actual file size
  372.     mov    ax,totlen
  373.     mov    si,offset vtlen
  374.     call    format
  375.  
  376.     mov    dx,totsize+2        ; total achive file size
  377.     mov    ax,totsize
  378.     mov    si,offset vtsize
  379.     call    format
  380.  
  381. ; reduce the total size/length to word values
  382.  
  383.     mov    bx,totlen        ; get actual file size
  384.     mov    ax,totlen+2
  385.     mov    cx,totsize        ; length of file in archive
  386.     mov    dx,totsize+2
  387. arcv2b: or    ax,ax            ; big number?
  388.     jz    arcv2c            ; nope, can use it
  389.     shr    ax,1            ; yup, divide by two
  390.     rcr    bx,1
  391.     shr    dx,1
  392.     rcr    cx,1
  393.     jmp    short arcv2b
  394.  
  395. arcv2c: mov    si,offset vtsf-5    ; format stowage factor
  396.     mov    ax,bx
  397.     mov    sign,' '                ; whata kludge
  398.     cmp    ax,cx            ; arc is bigger than orig?
  399.     jb    arcv2c1
  400.     sub    ax,cx            ; amount saved
  401.     jmp    short arcv2f
  402. arcv2c1:
  403.     sub    ax,cx
  404.     neg    ax
  405.     mov    sign,'-'
  406. arcv2f:
  407.     mul    hundred         ; to percentage
  408.     add    ax,50
  409.     adc    dx,0            ; round up percent
  410.     or    bx,bx            ; empty file?
  411.     jnz    arcv2d
  412.     mov    ax,100
  413.     jmp    short arcv2e
  414.  
  415. arcv2d: div    bx
  416. arcv2e: sub    dx,dx
  417.     call    format
  418.  
  419.     mov    al,sign
  420.     mov    vtsf,al
  421.     print    vthdr            ; display totals
  422.  
  423. skip_totals:
  424.     call    closarc
  425.     jmp    getnext
  426.  
  427.     page
  428. ;
  429. ;    format single line for each member
  430.  
  431. arcvgo:
  432.     mov    di,offset vname     ; copy file name
  433.     mov    si,offset archdr.mbrname
  434.     mov    cx,13
  435. arcv3:
  436.     lodsb
  437.     cmp    al,0            ; end of name?
  438.     je    arcv4
  439.     stosb
  440.     loop    arcv3
  441.     jmp    short arcv5
  442. arcv4:
  443.     mov    al,' '                  ; pad with blanks
  444.     rep    stosb
  445. arcv5:
  446.     inc    totmbrs
  447.  
  448. ; reduce the size/length to word values
  449.  
  450.     mov    bx,archdr.mbrlen    ; get actual file size
  451.     mov    ax,archdr.mbrlen+2
  452.  
  453.     mov    cx,archdr.mbrsize    ; length of file in archive
  454.     mov    dx,archdr.mbrsize+2
  455.  
  456. arcv51: or    ax,ax            ; big number?
  457.     jz    arcv52            ; nope, can use it
  458.     shr    ax,1            ; yup, divide by two
  459.     rcr    bx,1
  460.     shr    dx,1
  461.     rcr    cx,1
  462.     jmp    short arcv51
  463.  
  464. arcv52: mov    si,offset vfactor-5    ; format stowage factor
  465.     mov    ax,bx            ; low word of actual size
  466.     mov    sign,' '
  467.     cmp    ax,cx            ; arc member is larger?
  468.     jb    arcv520
  469.     sub    ax,cx            ; amount saved
  470.     jmp    arcv56
  471. arcv520:
  472.     sub    ax,cx
  473.     neg    ax
  474.     mov    sign,'-'
  475. arcv56:
  476.     mul    hundred         ; to percentage
  477.     add    ax,50
  478.     adc    dx,0            ; round up percent
  479.     or    bx,bx            ; empty file?
  480.     jnz    arcv53
  481.     mov    ax,100
  482.     jmp    short arcv54
  483.  
  484. arcv53: div    bx
  485. arcv54: sub    dx,dx
  486.     cmp    ax,100            ; archive fouled?
  487.     jbe    arcv55
  488.     sub    ax,ax
  489. arcv55:
  490.     call    format
  491.     mov    al,sign
  492.     mov    vfactor,al
  493.  
  494.     sub    bx,bx            ; determine style
  495.     mov    bl,archdr.mbrcode
  496.     mov    cl,3            ; eight bytes each entry
  497.     shl    bx,cl
  498.     lea    si,styles-8[bx]     ; get ptr to style name
  499.     mov    di,offset vstyle
  500.     mov    cx,8
  501.     rep    movsb
  502.  
  503.     mov    si,offset vsize     ; format file size
  504.     mov    dx,archdr.mbrsize+2
  505.     mov    ax,archdr.mbrsize
  506.     add    totsize,ax
  507.     adc    totsize+2,dx
  508.     call    format
  509.  
  510.     mov    si,offset vlength    ; format file length
  511.     mov    dx,archdr.mbrlen+2
  512.     mov    ax,archdr.mbrlen
  513.     add    totlen,ax
  514.     adc    totlen+2,dx
  515.     call    format
  516.  
  517.     mov    ax,archdr.mbrdate    ; format file date
  518.     call    getdate
  519.  
  520.     mov    ax,archdr.mbrtime    ; format file time
  521.     call    gettime
  522.  
  523.     mov    ax,archdr.mbrcrc    ; format crc in hex
  524.     mov    di,offset vcrc
  525.     call    cvh
  526.  
  527.     print    vline            ; display this file info
  528.  
  529.     mov    cx,word ptr archdr.mbrsize+2
  530.     mov    dx,word ptr archdr.mbrsize
  531.     add    dx,incurl        ; add current file offset
  532.     adc    cx,0
  533.     add    cx,incurh
  534.     mov    ax,4200h        ; skip over file data
  535.     mov    bx,archdl
  536.     int    21h
  537.     mov    incurh,dx        ; new position
  538.     mov    incurl,ax
  539.     mov    inlen,0         ; reset read buffer
  540.     jmp    arcvnext
  541.  
  542.     subttl    ' - miscellaneous subroutines'
  543.     page
  544.  
  545. openarc proc    near            ; open new archive
  546.     push    bx
  547.     mov    byte ptr errlvl,0
  548.     mov    dx,offset arcname
  549.     mov    ax,3d00h        ; for input
  550.     int    21h
  551.     jc    openerr
  552.     mov    archdl,ax        ; save file handle
  553.     clc
  554.     pop    bx
  555.     ret
  556. openerr:
  557. ;    cmp    flags,0         ; find-first or open?
  558. ;    je    open_err
  559. ;    jmp    nofiles
  560. open_err:
  561.     printl    'Unable to open archive: '
  562.     print    arcname
  563.     jmp    error
  564. openarc endp
  565.  
  566.  
  567. closarc proc    near
  568.     push    bx
  569.     mov    bx,archdl        ; previous handle
  570.     or    bx,bx            ; already open?
  571.     jz    closed
  572.     mov    ah,3eh            ; yes, so close it
  573.     int    21h
  574. closed: mov    archdl,0
  575.     pop    bx
  576.     ret
  577. closarc endp
  578.  
  579. ;
  580. ;    print string like int 21h function 9
  581.  
  582. prints    proc    near            ; dx has offset to string
  583.     push    si            ;  ending in char x'ff'
  584.     push    bx
  585.     push    cx
  586.     mov    si,dx
  587.     sub    cx,cx
  588. ps1:    lodsb
  589.     cmp    al,stopper        ; ending hex ff?
  590.     je    ps9
  591.     inc    cx            ; incr text length
  592.     jmp    ps1
  593.  
  594. ps9:    mov    ah,40h            ; write to file
  595.     mov    bx,outhdl        ; using std out or temp file
  596.     int    21h
  597.  
  598.     pop    cx            ; recover registers
  599.     pop    bx
  600.     pop    si
  601.     ret
  602. prints    endp
  603.  
  604.     page
  605. ;
  606. ;    format the time
  607.  
  608. time    record    hour:5,min:6,sec:5    ;packed time
  609.  
  610. gettime proc    near            ;format the date
  611.     mov    di,offset vtime
  612.     or    ax,ax            ;it is zero?
  613.     jz    gottime
  614.     push    ax            ;save date
  615.     and    ax,mask hour        ;get hour part
  616.     mov    cl,hour         ;bits to shift
  617.     shr    ax,cl
  618.     call    cnvrt1
  619.     stosw
  620.     mov    al,':'
  621.     stosb
  622.  
  623. gt3:    pop    ax            ;get the time back
  624.     and    ax,mask min        ;get min part
  625.     mov    cl,min            ;bits to shift
  626.     call    cnvrt
  627.     stosw
  628. gottime:ret
  629. gettime endp
  630.  
  631. cnvrt2    proc    near            ;convert to ascii
  632.     call    cnvrt
  633.     cmp    al,'0'                  ;suppress leading zero
  634.     jne    cnvrtd
  635.     mov    al,' '
  636.     ret
  637.  
  638. cnvrt:    shr    ax,cl
  639. cnvrt1: aam                ;make al into bcd
  640.     or    ax,'00'                 ; and to ascii
  641.     xchg    al,ah
  642. cnvrtd: ret
  643. cnvrt2    endp
  644.  
  645.     page
  646. ;
  647. ;    format the date
  648.  
  649. date    record    yr:7,mo:4,dy:5        ;packed date
  650.  
  651. getdate proc    near            ;format the date
  652.     or    ax,ax            ;is it zero?
  653.     jz    gotdate
  654.     push    ax            ;save date
  655.     and    ax,mask yr        ;get year part
  656.     mov    cl,yr            ;bits to shift
  657.     call    cnvrt
  658.     mov    di,offset vyear
  659.     or    al,'8'                  ;adjust for base year
  660.     stosw
  661.  
  662.     pop    bx            ;get the date back
  663.     push    bx            ;save it
  664.     and    bx,mask mo        ;get month part
  665.     mov    cl,mo            ;bits to shift
  666.     shr    bx,cl
  667.     add    bx,bx            ; form month table index
  668.     add    bx,bx
  669.     lea    si,word ptr months-4[bx]
  670.     mov    cx,3
  671.     mov    di,offset vmonth
  672.     rep    movsb
  673.  
  674.     pop    ax            ;get the date back
  675.     and    ax,mask dy        ;get day part
  676.     mov    cl,dy            ;bits to shift
  677.     call    cnvrt
  678.     mov    di,offset vdate
  679.     stosw
  680. gotdate:ret
  681. getdate endp
  682.  
  683.     page
  684. ;
  685. ; ripped from sdir.asm. how does this work?
  686.  
  687. ddptr    dw    0
  688.  
  689. format    proc    near    ;formats a 32 bit integer in dx:ax
  690.     push    bp    ; to ds:si
  691.     push    bx
  692.     push    di
  693.     push    si
  694.     mov    ddptr,si    ;addr of target field
  695.     mov    di,dx        ;routine uses di:si
  696.     mov    si,ax
  697.     call    printdd
  698.     pop    si
  699.     pop    di
  700.     pop    bx
  701.     pop    bp
  702.     ret
  703.  
  704. printdd:
  705.     xor    ax,ax        ;zero out the
  706.     mov    bx,ax        ; working
  707.     mov    bp,ax        ; registers.
  708.     mov    cx,32        ;# bits of precision
  709. j1:    shl    si,1
  710.     rcl    di,1
  711.     xchg    bp,ax
  712.     call    j6
  713.     xchg    bp,ax
  714.     xchg    bx,ax
  715.     call    j6
  716.     xchg    bx,ax
  717.     adc    al,0
  718.     loop    j1
  719.     mov    cx,1710h
  720.     mov    ax,bx
  721.     call    j2
  722.     mov    ax,bp
  723. j2:    push    ax
  724.     mov    dl,ah
  725.     call    j3
  726.     pop    dx
  727. j3:    mov    dh,dl
  728.     shr    dl,1        ;move high
  729.     shr    dl,1        ; nibble to
  730.     shr    dl,1        ; the low
  731.     shr    dl,1        ; position.
  732.     call    j4
  733.     mov    dl,dh
  734. j4:    and    dl,0fh        ;mask low nibble
  735.     jz    j5        ;if not zero
  736.     mov    cl,0
  737. j5:    dec    ch
  738.     and    cl,ch
  739.     or    dl,'0'          ;fold in ascii zero
  740.     sub    dl,cl
  741.     mov    bx,ddptr
  742.     mov    [bx],dl     ;ptr to next target field
  743.     inc    ddptr
  744.     ret
  745.  
  746. j6:    adc    al,al
  747.     daa
  748.     xchg    al,ah
  749.     adc    al,al
  750.     daa
  751.     xchg    al,ah
  752.     ret
  753. format    endp
  754.  
  755.     page
  756. cvh    proc    near        ; convert 16-bit binary word in ax
  757.     push    di        ; to hex ASCII string at ds:di
  758.     push    bx        ; save registers
  759.     push    cx
  760.     push    dx
  761.  
  762.     mov    dx,ax        ; save 16-bits
  763.  
  764.     mov    bl,dh        ; third nibble
  765.     mov    cl,4
  766.     shr    bl,cl
  767.     mov    al,hexchar[bx]
  768.     stosb
  769.  
  770.     mov    bl,dh        ; last nibble
  771.     and    bl,0fh
  772.     mov    al,hexchar[bx]
  773.     stosb
  774.  
  775.     mov    bl,dl        ; first nibble
  776.     mov    cl,4
  777.     sub    bh,bh
  778.     shr    bl,cl        ; isolate
  779.     mov    al,hexchar[bx]
  780.     stosb
  781.  
  782.     mov    bl,dl        ; second nibble
  783.     and    bl,0fh        ; isolate
  784.     mov    al,hexchar[bx]
  785.     stosb
  786.     pop    dx        ; restore registers
  787.     pop    cx
  788.     pop    bx
  789.     pop    di
  790.     ret            ; return
  791.  
  792. hexchar db    '0123456789ABCDEF'
  793. cvh    endp
  794.  
  795.     subttl    ' - i/o subroutines'
  796.     page
  797.  
  798. getc    proc    near            ; return next byte in al
  799.     push    si            ;  or cf=1 for eof
  800. getc1:
  801.     dec    inlen            ; any left in buffer
  802.     jge    getc2            ; yes, pick it up
  803.     call    getblk
  804.     jnc    getc1
  805.     pop    si            ; return cf=1 at eof
  806.     ret
  807. getc2:
  808.     mov    si,inptr        ; offset to next byte
  809.     lodsb
  810.     mov    inptr,si
  811.     add    incurl,1        ; bump file offset
  812.     adc    incurh,0
  813.     pop    si
  814.     ret
  815. getc    endp
  816.  
  817.  
  818. getblk    proc    near            ; read next block
  819.     push    bx
  820.     push    cx
  821.     push    dx
  822.     mov    ah,3fh            ; read from handle
  823.     mov    bx,archdl        ; arc file handle
  824.     mov    cx,inbufsz        ; input buffer size
  825.     mov    dx,offset inbuf     ; offset to input buffer
  826.     mov    inptr,dx
  827.     int    21h
  828.     jc    getblkr         ; oops
  829.     or    ax,ax            ; anything read?
  830.     jnz    getblka
  831.     stc                ; no, set cf=1 for eof
  832.     jmp    short getblkx        ; and exit
  833. getblka:
  834.     mov    inlen,ax        ; return count of bytes read
  835. getblkx:
  836.     pop    dx
  837.     pop    cx
  838.     pop    bx
  839.     ret
  840.  
  841. getblkr:
  842.     printl    'I/O error reading '
  843.     print    arcname
  844.     jmp    error            ; gotta quit
  845. getblk    endp
  846.  
  847.     subttl    '--- load next archive header'
  848.     page
  849.  
  850. gethdr    proc    near
  851.     mov    cx,132            ; gotta look for the damn thing
  852. gethdr2:
  853.     call    getc            ; get next file byte
  854.     jc    gethdrr1        ; premature eof
  855.     cmp    al,arcmark        ; start of header?
  856.     je    gethdr3         ; yup, let's start cookin
  857.     loop    gethdr2
  858. gethdrr1:
  859.     printl    'Invalid archive format!'
  860.     jmp    error
  861.  
  862. gethdr3:
  863.     call    getc            ; get version code
  864.     jc    gethdrr1
  865.     mov    archdr.mbrcode,al
  866.     cmp    al,arcver        ; reasonable code?
  867.     ja    gethdrr1        ; nope, funny stuff
  868.     cmp    al,0            ; archive eof?
  869.     je    gethdr9         ; yup done
  870.  
  871.     mov    cx,13            ; get member name
  872.     mov    di,offset archdr.mbrname
  873. gethdr4:
  874.     call    getc
  875.     jc    gethdrr1
  876.     stosb
  877.     loop    gethdr4
  878. gethdr5:
  879.     mov    cx,10            ; length remaining
  880.     cmp    archdr.mbrcode,1    ; old format?
  881.     je    gethdr6         ; yes, it's short
  882.     mov    cl,14
  883. gethdr6:
  884.     mov    di,offset archdr.mbrsize
  885. gethdr7:
  886.     call    getc
  887.     jc    gethdrr1
  888.     stosb
  889.     loop    gethdr7
  890. gethdr8:
  891.     cmp    archdr.mbrcode,1    ; old format?
  892.     jne    gethdr9         ; if so, it's short
  893.     mov    si,offset mbrsize
  894.     mov    di,offset mbrlen
  895.     mov    cx,4
  896.     rep    movsb
  897. gethdr9:
  898.     clc
  899.     ret
  900.  
  901. gethdrr2:
  902.     printl    'Invalid archive header'
  903.     jmp    error
  904. gethdr    endp
  905.  
  906.     subttl    '--- i/o data areas'
  907.     page
  908.  
  909. arcv    endp
  910.  
  911. archdr    db    64 dup (0)        ; i/o area for a header
  912.  
  913. inbuf    db    inbufsz dup (0)
  914.  
  915. cseg    ends
  916.     end    arcv
  917.